/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
// pfdialog.hpp
//
// PegFileDialog capable of being used for opening, saving and 'saving as' 
// a file on Unix style OS (uses POSIX style directory routines).
// This class may be optionally included in the standard PEG library if
// needed, but is originally intended to be used along with the PEG
// utilities (WindowBuilder, ImageConvert and FontCapture).
//
// Author: Jim DeLisle
//
// Copyright (c) 1998-2003 Swell Software 
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software
// is strictly prohibited.
//
// Notes:
//
//    This class is intended for use on Unix style OS's only. For Win32
//  development platforms, use the standard Win32 file dialog box.
//
//  To do:
//  
//  1.) Sort the directory and file listings - DONE
//  2.) Allow the user to enter a file name in the selection string
//  3.) Allow the user to navigate by entering directory names or ".."
//      in the selection string.
//  4.) Make the dialog sizeable, coercing the controls to position
//      themselves accordingly.
//  5.) Filtering (user defined and application defined) - DONE for
//      application defined.
//
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

#ifndef PEG_FILE_DIALOG_HPP
#define PEG_FILE_DIALOG_HPP

/*---------------------------------------------------------------------------*/
// Constants for return values and modes of operation
/*---------------------------------------------------------------------------*/
const PEGINT PFD_ERROR          = -1;
const PEGINT PFD_NOOPERATION    = 0;

const PEGINT PFD_FILEOPEN       = 0x01;
const PEGINT PFD_FILESAVEAS     = 0x02;

const PEGINT PFD_CREATEPROMPT       = 0x10;
const PEGINT PFD_FILEMUSTEXIST      = 0x20;
const PEGINT PFD_CREATETESTFILE     = 0x40;
const PEGINT PFD_OVERWRITEPROMPT    = 0x80;

const PEGUINT PFD_BUFFERLEN        = 257;

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
class PegFileFilter
{
    public:
        PegFileFilter();
        PegFileFilter(const char* pFilter);
        ~PegFileFilter();

        // Accessors
        PEGUINT GetFilterCount() const { return mFilterCount; }
        char** GetFilterList() const { return mpFilterList; }
        const char* GetFilterName() const 
        {
            return mpFilterName;
        }

        PEGUINT Set(const char* pFilter);

    private:
        void Reset();

        char*    mpFilterName;
        char**   mpFilterList;
        PEGUINT  mFilterCount;
};

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
class PegListSortButton : public PegTextButton
{
    public:
        PegListSortButton(PegRect& Rect, const PEGUINT StringId, 
                          PEGUINT ID, PEGUINT Style);
        ~PegListSortButton();
        
        // Overrides
        virtual void Draw(const PegRect &Invalid);
        
        PEGBOOL GetStartLow() const { return mStartLow; }
        void SetStartLow(PEGBOOL Set, PEGBOOL Redraw = TRUE) 
        { 
            mStartLow = Set;
            if(Redraw)
            {
                Invalidate();
                Draw(mReal);
            }
        }
        
    protected:
        PEGBOOL    mStartLow;
};

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
class PegFileDialog : public PegDialog
{
    public:
        PegFileDialog(const PEGUINT  TitleId, PEGINT Left = -1,
                      PEGINT Top = -1);

        PegFileDialog(const PEGCHAR *Title, PEGINT Left = -1,
                        PEGINT Top = -1);

        virtual ~PegFileDialog();

        virtual PEGINT Execute();
        PEGINT GetOperation() const { return(mOperation); }
        virtual PEGINT Message(const PegMessage &Mesg);

        void SetDefNewExt(char *pExt)
        {
            mpDefNewExt = pExt;
        }
        void SetFilter(const char *pFilter);
        PEGBOOL SetMode(PEGINT Operation, PEGCHAR *pBuffer,
                PEGUINT BuffSize, const char *pStartNode = NULL);

        // Callbacks for qsort operations
        static int SortDirList(const void *, const void *);
        static int SortFileList(const void *, const void *);

    protected:
        char* AddDefExtToFileName(char *pFileName);
        char* BuildFileName();
        PEGBOOL BuildNewDirName(const char *pAppendDir);
        PEGBOOL CheckFileCreate(const char *pFileName);
        PEGBOOL CheckFileExists(const char *pFileName);

        void ClearDirList();
        void ClearFileList();
        void ClearFileName();

       #if defined(PEG_UNICODE)
        char* ConvertDataGet(const PEGCHAR *pData);
       #endif

        void FormatFilter(char *pBuffer, PEGUINT BufLen,
                          const PegFileFilter *pFilter);
        void RepopulateDirList();
        void RepopulateFileList();
        void ResetFilter();
        void StoreFilter(const char *pFilter);

        PEGBOOL TryChangeDir(const char *pPath);
        void UpdateFilter();
        void UpdatePresentDir();
        PEGBOOL ValidateEntry();

        enum ControlIDs{
            IDB_UPDIR = 101,
            IDB_HOME,
            IDB_REFRESH,
            IDB_VIEWALL,
            IDB_APPLYFILTER,
            IDB_SORTDIR,
            IDB_SORTFILE,
            IDC_DIRLIST,
            IDC_FILELIST,
            IDC_DIRPROMPT,
            IDC_FILEPROMPT,
            IDC_SELECTION,
            IDC_PRESENTDIR
        };

        PegVertList  *mpDirList;
        PegVertList  *mpFileList;
        PegEditField *mpFileString;
        PegListSortButton *mpSortDir;
        PegListSortButton *mpSortFile;
        PegTextButton *mpOk;
        PegTextButton *mpCancel;
        PegDecoratedButton *mpHome;
	PegDecoratedButton *mpUpDir;        
	PegDecoratedButton *mpRefresh;
        PegFileFilter *mpCurrentFilter;
        PegFileFilter **mpFilterList;
        PegPrompt    *mpPresentDir;
        PegPrompt    *mpFilter;
        PEGCHAR      *mpFileNameBuffer;
        char         *mpLastValidDir;
        char         *mpDefNewExt;
        PEGUINT       mFileNameBufferLen;
        PEGUINT       mFilterCount;
        PEGINT        mReturnCode;
        PEGINT        mOperation;
        PEGBOOL       mViewAll;
        PEGBOOL       mFilterActive;

        static PEGBOOL     mSortDirLowToHigh;
        static PEGBOOL     mSortFileLowToHigh;

};

#endif  // PEG_FILE_DIALOG_HPP



